package com.sig.opengl;

import java.util.ArrayList;
import java.util.List;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import com.sig.formes.*;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;

public class MyGLRenderer implements GLSurfaceView.Renderer {

	private float[] mMVPMatrix = new float[16];
	private float[] mProjMatrix = new float[16];
	private float[] mVMatrix = new float[16];

	public volatile List<IForme> _formes = new ArrayList<IForme>();

	public MyGLRenderer(){

	}
	
	public void onResume() {
		
		Matrix.setIdentityM(mMVPMatrix, 0);
		Matrix.setIdentityM(mProjMatrix, 0);
		Matrix.setIdentityM(mVMatrix, 0);
		
		GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
		for(IForme f : _formes){
			f.recreer();
		}
		
	}

	@Override
	public void onSurfaceCreated(GL10 unused, EGLConfig config) {
		
		// Set the background frame color
		GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		//if(_formes.isEmpty())
		//	ajouterFormes();
	}
	
	/*
	public void ajouterFormes(){
		Forme.ajouterFormes(_formes);
	}*/
	
	public void ajouterFormes(List<IForme> formes) {
		_formes.addAll(formes);
	}

	@Override
	public void onDrawFrame(GL10 unused) {
		synchronized(this) {
		//ajouterFormes();
			if(_formes != null && !_formes.isEmpty()){
				// Draw background color
				GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

				// Set the camera position (View matrix)
				Matrix.setLookAtM(mVMatrix, 0, 0, 0, 4, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

				// Calculate the projection and view transformation
				Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);

				//draw

				for(IForme polyedre : _formes){			
					polyedre.draw(mMVPMatrix);

					// Calculate the projection and view transformation
					Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);


				}
			}
		}

	}


	@Override
	public void onSurfaceChanged(GL10 unused, int width, int height) {
		// Adjust the viewport based on geometry changes,
		// such as screen rotation
		GLES20.glViewport(0, 0, width, height);

		float ratio = (float) width / height;

		// this projection matrix is applied to object coordinates
		// in the onDrawFrame() method
		Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

	}

	public static int loadShader(int type, String shaderCode){
		int shader = GLES20.glCreateShader(type);
		// create a vertex shader type (GLES20.GL_VERTEX_SHADER)
		// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)

		// add the source code to the shader and compile it
		GLES20.glShaderSource(shader, shaderCode);
		GLES20.glCompileShader(shader);

		return shader;
	}

	/**
	 * Utility method for debugging OpenGL calls. Provide the name of the call
	 * just after making it:
	 *
	 * <pre>
	 * mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
	 * MyGLRenderer.checkGlError("glGetUniformLocation");</pre>
	 *
	 * If the operation is not successful, the check throws an error.
	 *
	 * @param glOperation - Name of the OpenGL call to check.
	 */
	public static void checkGlError(String glOperation) {
		int error;
		while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
			System.err.println(glOperation + ": glError " + error);
			throw new RuntimeException(glOperation + ": glError " + error);
		}
	}


	private float _previousX;
	private float _previousY;
	private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
	
	public void rotate(float x, float y, GLSurfaceView surfaceView){
		
		float dx = x - _previousX;
		float dy = y - _previousY;

		// reverse direction of rotation above the mid-line
		if (y > surfaceView.getHeight() / 2) {
			dx = dx * -1 ;
		}

		// reverse direction of rotation to left of the mid-line
		if (x < surfaceView.getWidth() / 2) {
			dy = dy * -1 ;
		}
		
		if(_formes != null && _formes.size()>=4){
			_formes.get(0).addAngle( dx+dy * TOUCH_SCALE_FACTOR);
			_formes.get(1).addAngle( dx+dy * TOUCH_SCALE_FACTOR );
			_formes.get(2).addAngle( -(dx+dy * TOUCH_SCALE_FACTOR));
			_formes.get(3).addAngle( dx+dy * TOUCH_SCALE_FACTOR);
			if(_formes.size()>=5)
				_formes.get(4).addAngle( -(dx+dy * TOUCH_SCALE_FACTOR));  
		}
		

		_previousX = x;
		_previousY = y;
		
	}

}


